package com.ly.gen.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import com.ly.common.core.exception.ServiceException;
import com.ly.common.core.utils.SpringUtils;
import com.ly.gen.rowMapper.FieldRowMapper;
import com.ly.gen.entity.GenDataTable;
import com.ly.gen.entity.GenDataTableColumn;
import com.ly.gen.entity.GenField;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据库工具类
 *
 * @author luoyun
 * @Date: 2025/6/13 13:52
 * @Note:
 */
@Slf4j
public class GenDbUtils {

    public static JdbcTemplate getJdbcTemplate(){
        return SpringUtils.getBean(JdbcTemplate.class);
    }

    /**
     * 快速清空表
     * @desc
     * TRUNCATE TABLE users
     * DROP TABLE IF EXISTS
     * @param tableName
     */
    public static void truncateTable(String tableName){
        String sql =  "truncate table "+tableName;
        boolean checkFlag = StrUtil.startWith(tableName, "gen_");
        if(!checkFlag){
            throw new ServiceException("操作非法：不允许删除表");
        }
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        jdbcTemplate.update(sql);
    }

    /**
     * 快速清空表
     * @desc
     * alter table users change column `seq_key` `id` varchar(64) not null comment '主键' first, drop primary key,add primary key (`id`) using btree;
     * @param tableName
     */
    public static void updateTableId(String tableName){
        String sql = "alter table _tab change column `seq_key` `id` varchar(64) not null comment '主键' first, drop primary key,add primary key (`id`) using btree;";
        sql = sql.replace("_tab",tableName);
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        jdbcTemplate.update(sql);
    }

    public static Db getDb() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jeecg-boot");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        Db db2 = Db.use(dataSource);
        return db2;
    }

    /**
     * 获取全量表
     *
     * @desc SELECT * FROM information_schema.tables WHERE table_schema = DATABASE() ORDER BY table_name
     */
    public static List<GenDataTable> getAllTable() {
        String sql = "SELECT * FROM information_schema.tables WHERE table_schema = DATABASE() ORDER BY table_name";
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        // spring方式自动处理，可以帮忙检测数据错误
        // List<GenDataTable> tableList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(GenDataTable.class));
        List<GenDataTable> tableList = jdbcTemplate.query(sql, (rs, rowNum) -> {
            GenDataTable table = new GenDataTable();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i).toLowerCase();
                Object columnValue = rs.getObject(columnName);
                BeanUtil.setFieldValue(table, StrUtil.toCamelCase(columnName), columnValue);
                table.setDisplayOrder(i);
            }
            return table;
        });
        return tableList;
    }

    /**
     * 获取表字段-field
     *
     * @return
     * @desc select * from information_schema.columns where table_schema = DATABASE() and table_name = ?
     */
    public static List<GenDataTableColumn> getColumnByTableName(String tableName) {
        String sql = "select * from information_schema.columns where table_schema = DATABASE() and table_name = ? ORDER BY ordinal_position";
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            list = jdbcTemplate.queryForList(sql, new Object[]{tableName});
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new ServiceException("获取表数据异常！");
        }
        List<GenDataTableColumn> fields = jdbcTemplate.query(sql,  (rs, rowNum) -> {
            GenDataTableColumn column = new GenDataTableColumn();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i).toLowerCase();
                Object columnValue = rs.getObject(columnName);
                BeanUtil.setFieldValue(column, StrUtil.toCamelCase(columnName), columnValue);
                column.setDisplayOrder(i);
            }
            return column;
        },tableName);
        return fields;
    }

    /**
     * 获取指定表信息-mate
     *
     * @return
     * @desc SELECT * FROM information_schema.tables WHERE table_schema = DATABASE() and table_name = ?
     */
    public static Map<String, Object> getTableByName(String tableName) {
        String sql = "SELECT * FROM information_schema.tables WHERE table_schema = DATABASE() and table_name = ?";
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        Map<String, Object> map = new HashMap<>();
        try {
            map = jdbcTemplate.queryForMap(sql, new Object[]{tableName});
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new ServiceException("获取表数据异常！");
        }
        return map;
    }
    // 删除表：DROP TABLE IF EXISTS gen_data_table

    /**
     * 获取指定表信息-field
     *
     * @return
     * @desc select * from information_schema.columns where table_schema = DATABASE() and table_name = ?
     */
    public static List<GenField> getTableFieldByName(String tableName) {
        String sql = "select * from information_schema.columns where table_schema = DATABASE() and table_name = ? ORDER BY ordinal_position";
        JdbcTemplate jdbcTemplate = getJdbcTemplate();
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            list = jdbcTemplate.queryForList(sql, new Object[]{tableName});
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new ServiceException("获取表数据异常！");
        }
        List<GenField> fields = jdbcTemplate.query(sql, new FieldRowMapper(), tableName);
        return fields;
    }

    /**
     * 根据数据库类型返回对应的java类型
     *
     * @param type
     * @return
     */
    public static String getJavaType(String type) {
        switch (type) {
            case "date":
            case "datetime":
                return "java.time.LocalDateTime";
            case "bit":
            case "tinyint":
            case "int":
                return "java.lang.Integer";
            case "long":
            case "bigint":
                return "java.lang.Long";
            case "double":
            case "numeric":
            case "decimal":
                return "java.math.BigDecimal";
            case "varchar":
            case "char":
            case "json":
            case "longtext":
            case "mediumtext":
            case "text":
                return "java.lang.String";
            case "blob":
            case "mediumblob":
            case "longblob":
                return "byte[]";
            // 其他类型...
            default:
                return "java.lang.Object";
        }
    }
}
